﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace AtomITBackupUtility
{
    public partial class MainForm : Form
    {
        // Dictionary of backups
        List<Backup> m_ListOfBackups = new List<Backup>();

        // dialog used to collect info 
        NewBackup m_Dialog = new NewBackup();

        // list of filenames to remember
        string backupDataFile = @"C:\Program Files\Clean\cfg\_temp.dat";

        public MainForm()
        {
            InitializeComponent();
        }

        // Private Methods

        #region Private Medthods

        /// <summary>
        /// Adds a new backup procedure to the list of global backups
        /// </summary>
        /// <param name="name">A name for the backup</param>
        /// <param name="source">the folder to backup</param>
        /// <param name="destination">the folder to backup to</param>
        void AddNewBackup(string name,string source, string destination)
        {
            // creates new backup
            Backup l_newBackup = new Backup();
            l_newBackup.Name = name;
            l_newBackup.Source = source;
            l_newBackup.Destination = destination;

            // adds to global list
            m_ListOfBackups.Add(l_newBackup);

            RefreshData();
        }

        void RefreshData()
        {
            backupTasks.Items.Clear();

            foreach (Backup b in m_ListOfBackups)
            {
                backupTasks.Items.Add(b.Name);
            }
        }

        void SaveBackupData()
        {

            if (!File.Exists(backupDataFile))
                File.Create(backupDataFile);

            File.SetAttributes(backupDataFile, FileAttributes.Normal);
         
            StreamWriter writer = new StreamWriter(backupDataFile);

            

            foreach (Backup b in m_ListOfBackups)
            {
                

                writer.WriteLine(b.Name+","+b.Source+","+b.Destination);
 
            }

            writer.Close();
        }

        void LoadBackupData()
        {

            if (!File.Exists(backupDataFile))
                return;

            StreamReader reader = new StreamReader(backupDataFile);

            while (!reader.EndOfStream)
            {

                string line = reader.ReadLine();

                string[] data = line.Split(',');

                AddNewBackup(data[0], data[1], data[2]);

            }

            reader.Close();
        }

        private void PerformCurrentBackup()
        {
            // checks that there is a backup selected
            if (backupTasks.SelectedIndex != -1)
            {
                // check if thread is busy
                if (!backupThread.IsBusy)
                {
                    //starts background process to enable 'tracking' of backup
                    backupThread.RunWorkerAsync(backupTasks.SelectedIndex);

                }
                else
                {
                    MessageBox.Show("Thread Busy!");
                }
            }
            else
            {
                MessageBox.Show("There is no backup selected");
            }
        }

        private void FindBackups(int p)
        {
            string[] listOfDirs;

            List<string> listOfBackups = new List<string>();

            // get the directories within the backup folder
            listOfDirs = Directory.GetDirectories(m_ListOfBackups[p].Destination);

            bool found = false;

            // loop through all the directories
            foreach (string dir in listOfDirs)
            {
                // validate name
                string folderName = dir.Replace(m_ListOfBackups[p].Destination, "").Remove(0, 1);

                // check if folder is part of this backup task - by comparing with name
                if (folderName.StartsWith(m_ListOfBackups[p].Name))
                {
                    found = true;
                    listOfBackups.Add(folderName);
                }
            }

            previousBackups.Items.Clear();

            if (found)
            {

                previousBackups.Items.AddRange(listOfBackups.ToArray());
            }
        }

        void DeleteDirectory(object dir)
        {
            Directory.Delete((string)dir, true);
            lblCurrentStatus.Text = "Idle";

        }

        new void Update()
        {
            FindBackups(backupTasks.SelectedIndex);
        }

        #endregion

        // Event based

        #region Event Based Methods

        /// <summary>
        /// Shows the about box
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutAtomITBackupUtilityToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox aboutBox = new AboutBox();
            aboutBox.Show();
        }

        /// <summary>
        /// this is the work done by the seperate thread
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            // check that argument is present
            if (e.Argument == null)
            {
                MessageBox.Show("No Argument");
                return;
            }

            // use argument to cast index for the backup

            int index = (int)e.Argument;
            // create a temperary backup type
            Backup temp = m_ListOfBackups[index];
            // create the current timestamp used in the filename
            string fileDate = DateTime.Now.Day + "_" + DateTime.Now.Month + "_" + DateTime.Now.Year + "_" + DateTime.Now.Hour + "_" + DateTime.Now.Minute + "_" + DateTime.Now.Second;
            // report progress for thread
            backupThread.ReportProgress(5, "Preparing Backup Files");
            // copy files in source directory to destination.
            Files.CopyDirectory(temp.Source, temp.Destination + @"\" + temp.Name + "-" + fileDate + @"\", true, this, backupThread);

            return;

        }

        /// <summary>
        /// When progress has been made with the thread operation thie function is called
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">information from the thread</param>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressOfActions.Value = e.ProgressPercentage;
            lblCurrentStatus.Text = e.ProgressPercentage + "% - " + (string)e.UserState;
        }

        /// <summary>
        /// ran when the thread operation is completed
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e">information on thread.</param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            progressOfActions.Value = 0;
            lblCurrentStatus.Text = "Idle";


            this.Enabled = true;
        }

        private void backupNowToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            PerformCurrentBackup();

            this.Enabled = false;
        }

        private void btnAddNewBackup_Click(object sender, EventArgs e)
        {
            m_Dialog = new NewBackup();
            this.Hide();
            m_Dialog.Show();
            m_Dialog.Disposed += new EventHandler(l_Dialog_Leave);
        }

        void l_Dialog_Leave(object sender, EventArgs e)
        {
            AddNewBackup(NewBackup.m_NewBackupData.Name, NewBackup.m_NewBackupData.Source, NewBackup.m_NewBackupData.Destination);            
            this.Show();
        }

        private void btnStartSelectedBackup_Click(object sender, EventArgs e)
        {
            PerformCurrentBackup();

            this.Enabled = false;
        }

        private void saveBackupDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveBackupData();
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            LoadBackupData();
        }

        /// <summary>
        /// When a backup task is selected, the previousBackups panel will display all the backups done
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            FindBackups(backupTasks.SelectedIndex);
        }

        private void btnOpenPreviousBackup_Click(object sender, EventArgs e)
        {
            if (previousBackups.SelectedIndex == -1)
            {
                MessageBox.Show("No backup has been selected!");
            }
            else
            {
                string rootFolder = m_ListOfBackups[backupTasks.SelectedIndex].Destination + @"\";
                string backupFolder = (string)previousBackups.Items[previousBackups.SelectedIndex];
                string directoryPath = rootFolder + backupFolder;
                //MessageBox.Show();
                System.Diagnostics.Process.Start(@"explorer.exe", directoryPath);
            }
        }

        private void deleteBackup_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to delete?", "Confirm delete", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                string rootFolder = m_ListOfBackups[backupTasks.SelectedIndex].Destination + @"\";
                string backupFolder = (string)previousBackups.Items[previousBackups.SelectedIndex];
                string directoryPath = rootFolder + backupFolder;

                Thread t = new Thread(DeleteDirectory);
                t.Start((object)directoryPath);
            }

            lblCurrentStatus.Text = "Backup Deleting in Background";
            
        }



        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        #endregion

        

        

    }
}
